package com.zhanghe.study.proxy.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理
 */
public class TestDynamicProxy {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        MyInvationHandler myInvationHandler = new MyInvationHandler();
        Object obj = myInvationHandler.blind(realSubject);
        Subject sub = (Subject) obj;
        sub.action();
    }
}

// 接口
interface Subject{
    void action();
}

// 真正执行的方法，被代理类
class RealSubject implements Subject{

    @Override
    public void action() {
        System.out.println("被代理类开始执行");
    }
}

class MyInvationHandler implements InvocationHandler{

    // 实现了接口的被代理类的对象的声明
    Object obj;
    // 被代理类的实例
    // 返回一个代理类的对象
    public Object blind(Object obj){
        this.obj = obj;
        // ①使用被代理类的类加载器②被代理类的接口③代理类的实例
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }

    /**
     * 当通过代理类的对象被重写的方法调用时，都会转换为对invoke方法的调用
     * @param proxy 正在返回的代理对象，一般情况下，在invoke方法中不使用该对象
     * @param method 正在被调用的方法
     * @param args 调用方法时，传入的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        return method.invoke(obj,args);
    }
}
